package com.CityHunter.Request;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import android.util.Log;

import com.CityHunter.DataObject.Schedule;
import com.google.android.maps.GeoPoint;

public class DirectionAPIRequest {
	private String directionAPIPage;

	public DirectionAPIRequest(String directionAPIPage) {
		this.directionAPIPage = directionAPIPage;
	}

	public ArrayList<GeoPoint> directionAPI(Schedule schedule) {

		ArrayList<GeoPoint> path = new ArrayList<GeoPoint>();
		// Insert start point
		path.add(schedule.get(0).geoPoint());

		if (schedule.size() > 1) {

			// Get start and end GeoPoint from schedule
			String strStartGP, strEndGP, strWayPoints = "";
			strStartGP = GeoPointToString(schedule.get(0).geoPoint());
			strEndGP = GeoPointToString(schedule.get(schedule.size() - 1)
					.geoPoint());
			Log.d("Debug", "strStartGP = " + strStartGP + " strEndGP = "
					+ strEndGP);

			// Get waypoints from schedule
			for (int i = 1; i < schedule.size() - 1; i++) {
				strWayPoints += GeoPointToString(schedule.get(i).geoPoint());
				if (i < schedule.size() - 2) {
					strWayPoints += "%7C";
				}
			}
			Log.d("Debug", "strWayPoints = " + strWayPoints);

			String mode = "walking";
			String language = "zh-TW";
			String sensor = "false";
			
			
			// Declare String params
			String params = "";
			params += "?origin=" + strStartGP;
			params += "&destination=" + strEndGP;
			params += "&mode=" + mode;
			params += "&language=" + language;
			params += "&sensor=" + sensor;
			if (schedule.size() > 2)
				params += "&waypoints=" + strWayPoints;
			
			// Declare NameValuePair to store the data
			List<NameValuePair> nvp = new ArrayList<NameValuePair>();
			/*
			nvp.add(new BasicNameValuePair("origin", strStartGP));
			nvp.add(new BasicNameValuePair("destination", strEndGP));
			nvp.add(new BasicNameValuePair("mode", mode));
			nvp.add(new BasicNameValuePair("language", language));
			nvp.add(new BasicNameValuePair("sensor", sensor));
			if (schedule.size() > 2)
				nvp.add(new BasicNameValuePair("waypoints", strWayPoints));
			*/
			
			try {
				// Send get direction Request
				HttpPost httpRequest = new HttpPost(directionAPIPage + params);
				DefaultHttpClient httpclient = new DefaultHttpClient();
				// send request
				//httpRequest.setEntity(new UrlEncodedFormEntity(nvp, HTTP.UTF_8));
				// get response
				HttpResponse httpResponse = httpclient.execute(httpRequest);
				Log.d("Debug", "Sending Request : " + directionAPIPage + params);
				// if connection status is OK
				if (httpResponse.getStatusLine().getStatusCode() == 200) {
					String strResult = EntityUtils.toString(httpResponse
							.getEntity());
					JSONObject resultObj = new JSONObject(strResult);
					JSONArray routeArray = resultObj.getJSONArray("routes");
					JSONObject routesObj = routeArray.getJSONObject(0);
					JSONArray legs = routesObj.getJSONArray("legs");

					Log.d("Debug", "Connect successful");

					for (int x = 0; x < legs.length(); x++) {
						JSONArray steps = legs.getJSONObject(x).getJSONArray(
								"steps");

						for (int i = 0; i < steps.length(); i++) {
							JSONObject start_location = steps.getJSONObject(i)
									.getJSONObject("start_location");
							JSONObject end_location = steps.getJSONObject(i)
									.getJSONObject("end_location");
							// desc =
							// steps.getJSONObject(i).getString("html_instructions")
							// +
							// "\n";
							int lat = (int) (Double.parseDouble(end_location
									.getString("lat")) * 1E6);
							int lng = (int) (Double.parseDouble(end_location
									.getString("lng")) * 1E6);
							GeoPoint gp = new GeoPoint(lat, lng);
							path.add(gp);

						}
					}
				}

				Log.d("Debug", "Response Result : " + path.size());
			} catch (Exception e) {
				Log.e("Error", e.getMessage().toString());
			}
		}
		return path;
	}

	private String GeoPointToString(GeoPoint gp) {
		String strReturn = "";
		try {
			if (gp != null) {
				double geoLatitude = (int) gp.getLatitudeE6() / 1E6;
				double geoLongitude = (int) gp.getLongitudeE6() / 1E6;
				strReturn = String.valueOf(geoLatitude) + ","
						+ String.valueOf(geoLongitude);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return strReturn;
	}

}
